//
//  YLAlipayProcessor.swift
//  YLPaymentKit
//
//  Created by changhe on 2025/4/12.
//

import Foundation
import UIKit
import AlipaySDK

@objc
/// 支付宝支付处理器实现
public class YLAlipayProcessor: NSObject, YLPaymentProcessor {
    // MARK: - 属性
    
    /// 支付类型
    public var paymentType: YLPaymentType {
        return .alipay
    }
    
    /// 是否可用（支付宝SDK总是可用，因为不依赖应用是否安装）
    public var isAvailable: Bool {
        return true
    }
    
    /// 应用scheme
    private var scheme: String?
    
    /// 应用ID
    private var appId: String?
    
    /// 当前回调
    private var currentCallback: ((YLPaymentResult) -> Void)?
    
    /// 当前订单ID
    private var currentOrderId: String?
    
    // MARK: - 初始化与设置
    
    /// 设置交易更新回调
    public func setTransactionUpdatedCallback(_ callback: @escaping (YLTransactionInfo) -> Void) { }
    
    /// 初始化处理器
    public func setup(config: YLPaymentConfig) {
        // 保存应用scheme和appId
        self.scheme = config.alipayScheme
        self.appId = config.appId
    }
    
    // MARK: - 支付处理
    
    /// 处理支付（使用YLPaymentParams）
    public func handlePayment(params: YLPaymentParams, completion: @escaping YLPaymentCallback) {
        // 保存回调和订单ID
        self.currentCallback = completion
        self.currentOrderId = params.orderId
        
        let appScheme = self.scheme ?? "YLPaymentDemo"
        
        // 检查参数类型
        if let alipayParams = params as? YLAlipayParams {
            if let paymentString = alipayParams.paymentString {
                callAlipaySDK(orderInfo: paymentString, scheme: appScheme)
            } else if let amount = alipayParams.amount, let subject = alipayParams.subject {
                let orderInfo = buildOrderInfo(
                    orderId: alipayParams.orderId,
                    amount: amount,
                    subject: subject,
                    body: alipayParams.body,
                    notifyUrl: alipayParams.notifyUrl,
                    returnUrl: alipayParams.returnUrl
                )
                
                callAlipaySDK(orderInfo: orderInfo, scheme: appScheme)
            } else {
                completion(.failure(.invalidParameters))
                self.clearPaymentState()
            }
        } else {
            completion(.failure(.invalidParameters))
            self.clearPaymentState()
        }
    }
    
  
    // MARK: - URL回调处理
    
    /// 能否处理URL
    public func canHandleURL(_ url: URL) -> Bool {
        return url.host == "safepay" || url.scheme?.hasPrefix("alipay") == true
    }
    
    /// 处理URL回调
    public func handleURL(_ url: URL) -> Bool {
        if canHandleURL(url) {
            AlipaySDK.defaultService().processOrder(withPaymentResult: url, standbyCallback: { [weak self] resultDict in
                guard let self = self else { return }
                
                self.handleAlipayResult(resultDict)
            })
            return true
        }
        return false
    }
    
    // MARK: - 结果处理
    
    /// 处理支付宝返回结果
    private func handleAlipayResult(_ resultDict: [AnyHashable: Any]?) {
        guard let resultDict = resultDict else {
            self.currentCallback?(.failure(.other("支付宝返回结果为空")))
            self.clearPaymentState()
            return
        }
        
        // 解析支付结果
        if let resultStatus = resultDict["resultStatus"] as? String {
            switch resultStatus {
            case "9000": // 支付成功
                let info = resultDict as? [String: Any] ?? [:]
                
                let resultData = YLPaymentResultData(
                    orderId: self.currentOrderId ?? "",
                    transactionId: info["trade_no"] as? String ?? "",
                    productId: nil,
                    transactionDate: Date(),
                    originalTransactionId: nil,
                    rawInfo: info
                )
                
                self.currentCallback?(.success(resultData))
                
            case "6001": // 用户取消
                self.currentCallback?(.cancel)
                
            default: // 其他错误
                let errorMessage = "支付宝支付失败，状态码：\(resultStatus)"
                self.currentCallback?(.failure(.other(errorMessage)))
            }
        } else {
            self.currentCallback?(.failure(.other("支付宝返回结果解析失败")))
        }
        
        // 清除支付状态
        self.clearPaymentState()
    }
    
    // MARK: - 辅助方法
    
    /// 调用支付宝SDK
    private func callAlipaySDK(orderInfo: String, scheme: String) {
        // 调用支付宝SDK进行支付
        AlipaySDK.defaultService().payOrder(orderInfo, fromScheme: scheme, callback: { [weak self] resultDict in
            guard let self = self else { return }
            
            self.handleAlipayResult(resultDict)
        })
    }
    
    /// 构建支付参数
    private func buildOrderInfo(orderId: String, amount: Double, subject: String, 
                              body: String?, notifyUrl: String?, returnUrl: String?) -> String {
        // 构建支付参数
        var params: [String: String] = [
            "app_id": self.appId ?? "", 
            "method": "alipay.trade.app.pay",
            "charset": "utf-8",
            "sign_type": "RSA2",
            "timestamp": dateFormatter.string(from: Date()),
            "version": "1.0",
            "notify_url": notifyUrl ?? "",
            "biz_content": [
                "out_trade_no": orderId,
                "total_amount": String(format: "%.2f", amount),
                "subject": subject,
                "body": body ?? "",
                "product_code": "QUICK_MSECURITY_PAY"
            ].jsonString() ?? ""
        ]
        
        // 添加返回URL（如果有）
        if let returnUrl = returnUrl {
            params["return_url"] = returnUrl
        }
        
        // 构建查询字符串
        let orderInfo = params.map { "\($0.key)=\($0.value)" }.joined(separator: "&")
        
        // 注意：实际使用时需要对参数进行签名
        // 这里简化处理，实际项目中应该在服务端完成签名
        return orderInfo
    }
    
    /// 清除支付状态
    private func clearPaymentState() {
        self.currentCallback = nil
        self.currentOrderId = nil
    }
    
    // MARK: - 格式化工具
    
    /// 日期格式化器
    private lazy var dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter
    }()
}

private extension Dictionary where Key == String, Value == String {
    func jsonString() -> String? {
        do {
            let data = try JSONSerialization.data(withJSONObject: self, options: [])
            return String(data: data, encoding: .utf8)
        } catch {
            return nil
        }
    }
}
